<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            margin: 0;
            font-family: Arial, sans-serif;
        }
    </style>
</head>
<body>
    <sidebar-menu id="myMenu">
        <!-- 菜单配置 -->
        <script type="application/json">
            {
                "search": true,
                "items": [
                    {
                        "title": "仪表盘",
                        "icon": "📊",
                        "children": [
                            { "title": "概览", "icon": "👁️" },
                            {
                                "title": "统计",
                                "icon": "📈",
                                "children": [
                                    { "title": "实时数据", "icon": "⏱️" },
                                    { "title": "历史数据", "icon": "🕰️" }
                                ]
                            }
                        ]
                    },
                    {
                        "title": "设置",
                        "icon": "⚙️",
                        "children": [
                            { "title": "用户管理", "icon": "👤" },
                            { "title": "系统设置", "icon": "🖥️" }
                        ]
                    }
                ]
            }
        </script>
    </sidebar-menu>

    <script>
        class SidebarMenu extends HTMLElement {
            constructor() {
                super();
                this.attachShadow({ mode: 'open' });
                this.menuData = null;
                this.expanded = true;
                this.activeItem = null;
            }

            connectedCallback() {
                this._loadData();
                this._render();
                this._addEventListeners();
            }

            _loadData() {
                const configScript = this.querySelector('script[type="application/json"]');
                this.menuData = configScript ? JSON.parse(configScript.textContent) : { items: [] };
            }

            _render() {
                this.shadowRoot.innerHTML = `
                    <style>
                        :host {
                            display: block;
                            width: ${this.expanded ? '250px' : '60px'};
                            transition: width 0.3s;
                            background: #283746;
                            color: white;
                            height: 100vh;
                            position: relative;
                        }

                        .menu-container {
                            padding: 20px 0;
                        }

                        .search-box {
                            width: calc(100% - 20px);
                            padding: 10px;
                            display: ${this.menuData?.search ? 'block' : 'none'};
                        }

                        input {
                            width: calc(100% - 16px);
                            padding: 8px;
                            border-radius: 4px;
                            border: none;
                            background: #34495e;
                            color: white;
                        }

                        .menu-item {
                            padding: 0 0;
                            cursor: pointer;
                            display: flex;
                            align-items: flex-start;
                            flex-direction:column;
                            transition: background 0.3s;
                            position: relative;
                            span{
                                padding-top: 5px;
                                padding-bottom: 5px;
                                padding-left: 5px;
                            }
                        }

                        .menu-item:hover {
                            background: #34495e;
                        }

                        .icon {
                            margin-right: ${this.expanded ? '10px' : '0'};
                            transition: margin 0.3s;
                        }

                        .title {
                            display: ${this.expanded ? 'inline' : 'none'};
                            white-space: nowrap;
                        }

                        .children {
                            height: 0;
                            opacity: 0;
                            visibility: hidden;
                            overflow: hidden;
                            transition: all 1s;
                            background: rgb(0 0 0 / 30%);
                            width: 100%;
                        }

                        .children .menu-item{
                            padding: 0 0;
                        }
                        .expanded > .children {
                           visibility: visible;
                           height: auto;
                           opacity: 1;
                        }

                        .arrow {
                            margin-left: auto;
                            transition: transform 0.3s;
                            display: ${this.expanded ? 'inline-block' : 'none'};
                        }

                        .expanded>span .arrow{
                            transform: rotate(90deg);
                        }

                        .toggle-btn {
                            position: absolute;
                            right: 10px;
                            top: 10px;
                            cursor: pointer;
                            padding: 5px;
                            background: #34495e;
                            border-radius: 4px;
                        }

                        .active {
                            background: #3498db !important;
                        }
                    </style>

                    <div class="toggle-btn">${this.expanded ? '◀' : '▶'}</div>
                    <div class="menu-container">
                        ${this.menuData?.search ? `
                            <div class="search-box">
                                <input type="text" placeholder="搜索..." id="searchInput">
                            </div>
                        ` : ''}
                        <div class="menu-items">
                            ${this._renderMenuItems(this.menuData.items)}
                        </div>
                    </div>
                `;
            }

            _renderMenuItems(items = [], level = 0) {
                return items.map(item => `
                    <div class="menu-item" 
                         data-level="${level}" 
                         data-has-children="${!!(item.children?.length)}">
                       <span><span class="icon">${item.icon}</span>
                        <span class="title">${item.title}</span>
                        ${item.children?.length ? '<span class="arrow">▶</span>' : ''}
                        ${item.children?.length ? `
                        </span>
                            <div class="children">
                                ${this._renderMenuItems(item.children, level + 1)}
                            </div>
                        ` : ''}
                    </div>
                `).join('');
            }

            _addEventListeners() {
                this.shadowRoot.addEventListener('click', e => {
                    const menuItem = e.target.closest('.menu-item');
                    const toggleBtn = e.target.closest('.toggle-btn');

                    if (toggleBtn) {
                        this.expanded = !this.expanded;
                        this._toggleCollapse();
                        return;
                    }

                    if (!menuItem) return;

                    if (menuItem.dataset.hasChildren === 'true') {
                        // const arrow = menuItem.querySelector('.arrow');
                        // if (arrow) {
                        //     arrow.textContent = menuItem.classList.contains('expanded') ? '▶' : '▼';
                        // }

                        menuItem.classList.toggle('expanded');

                        if (!e.altKey && this.expanded) {
                            const siblings = Array.from(menuItem.parentElement.children)
                                .filter(child => child !== menuItem);
                            siblings.forEach(sib =>{
                                sib.classList.remove('expanded');
                                // sib.querySelector('.arrow').textContent = sib.classList.contains('expanded') ?  '▼':'▶' ;
                            });

                        }
                    } else {
                        console.log('选中菜单:', menuItem.querySelector('.title').textContent);
                        this._setActiveItem(menuItem);
                    }
                });

                this.shadowRoot.addEventListener('dblclick', e => {
                    if (e.target.closest('.menu-item')) {
                        this.shadowRoot.querySelectorAll('.expanded').forEach(el => {
                            el.classList.remove('expanded');
                        });
                    }
                });

                if (this.menuData?.search) {
                    this.shadowRoot.getElementById('searchInput').addEventListener('input', (e) => {
                        this._filterMenuItems(e.target.value.toLowerCase());
                    });
                }
            }

            _filterMenuItems(searchTerm) {
                this.shadowRoot.querySelectorAll('.menu-item').forEach(item => {
                    const text = item.querySelector('.title')?.textContent.toLowerCase() || '';
                    const matches = text.includes(searchTerm);
                    item.style.display = matches ? 'flex' : 'none';

                    if (matches) {
                        let parent = item.parentElement.closest('.menu-item');
                        while (parent) {
                            parent.classList.add('expanded');
                            parent = parent.parentElement.closest('.menu-item');
                        }
                    }
                });
            }

            _toggleCollapse() {
                this.style.width = this.expanded ? '250px' : '50px';
                this.shadowRoot.querySelector('.toggle-btn').textContent = this.expanded ? '◀' : '▶';

                this.shadowRoot.querySelectorAll('.title').forEach(el => {
                    el.style.display = this.expanded ? 'inline' : 'none';
                });

                this.shadowRoot.querySelectorAll('.arrow').forEach(el => {
                    el.style.display = this.expanded ? 'inline-block' : 'none';
                });

                this.shadowRoot.querySelectorAll('.icon').forEach(el => {
                    el.style.marginRight = this.expanded ? '10px' : '0';
                });
            }

            _setActiveItem(menuItem) {
                this.activeItem?.classList.remove('active');
                menuItem.classList.add('active');
                this.activeItem = menuItem;
            }
        }

        customElements.define('sidebar-menu', SidebarMenu);
    </script>
</body>
</html>